<!--
禁止修改!此文件是产品代码的一部分，后续可能变更或者不再开放。
若有问题，请参考前端相关二开文档。
-->
<template>
  <div class="home-item-box my-charts">
    <div class="header">
      <span>{{ $t('languages.common.workbanch.myCharts') }}</span>
      <span
        v-if="favoritesCharts.length > 0"
        class="manage-opt"
        @click="onManageEdit"
        >{{ $t('languages.common.workbanch.management') }}</span>
    </div>
    <div v-if="isLoading" class="loading-charts">
      <PageLoadingUnify :loading="isLoading" />
    </div>
    <template v-else>
      <div v-if="favoritesCharts.length > 0" class="box-content">
        <div
          v-for="(apprep, apprepIndex) in favoritesCharts"
          :key="apprepIndex"
          class="chart-item"
        >
          <template v-if="apprep.uuid && apprep.objectId">
            <SingleChartRender
              :key="apprepIndex"
              :apprep="apprep"
              :config="config"
            />
          </template>
        </div>
      </div>

      <default-content
        v-else
        :title="$t('languages.common.workbanch.chart')"
        @openManageModal="onManageEdit"
      />
    </template>
    <h3-popup
      :visible="manageEdit"
      :round="true"
      class="manage-edit-modal"
      maskClosable
      popupDirection="up"
      popupHeight="calc(100% - 44px)"
      @maskClick="popupClose"
    >
      <div class="manage-edit-box">
        <div class="manage-edit-header">
          <div class="manage-edit-name">
            <span>{{ $t('languages.common.workbanch.manageChart') }}</span>
          </div>
          <div class="close-modal">
            <span
              class="icon aufontAll h-icon-all-close"
              @click="popupClose"
            ></span>
          </div>
        </div>
        <div class="manage-edit-body">
          <div class="body-top">
            <div class="sub-title">
              {{ $t('languages.common.workbanch.added') }}
              <span
                class="count"
                :class="{ selected: selectedCharts.length > 0 }"
                >{{ selectedCharts.length }}</span>/<span>{{ maxFavoritesCharts }}</span>
            </div>
            <div v-if="selectedCharts.length > 0" class="sub-content">
              <draggable
                :list="selectedCharts"
                :options="dragOptions"
                handle=".item-dragable-icon"
                class="drags-area"
                chosenClass="chosen"
                ghostClass="ghost"
              >
                <div
                  v-for="(apprep, apprepIndex) in selectedCharts"
                  :key="apprepIndex"
                  class="tree-item report-list"
                >
                  <span class="tree-item-name">
                    <em
                      class="item-dragable-icon aufontAll h-icon-all-drag"
                    ></em>
                    <em class="icon aufontAll h-icon-all-sales-stage-o"></em>{{ apprep.title }}</span>
                  <em
                    class="icon aufontAll h-icon-all-minus-circle opt-icon"
                    @click="delApp(apprep, apprepIndex)"
                  ></em>
                </div>
              </draggable>
            </div>
            <div v-else class="empty-content">
              {{ $t('languages.common.workbanch.addTips2') }}
            </div>
          </div>
          <div class="body-bottom">
            <div class="sub-title">
              {{ $t('languages.common.workbanch.addable') }}
            </div>
            <div class="sub-content">
              <template v-for="(chartApp, index) in chartAppList">
                <div :key="index" class="app-info">
                  <div
                    class="tree-item app-list"
                    @click="onAppOrAppFormCollapse(chartApp)"
                  >
                    <em
                      class="icon aufontAll caret-icon"
                      :class="
                        chartApp.collapse
                          ? 'h-icon-all-caret-right'
                          : 'h-icon-all-caret-down'
                      "
                    ></em>
                    <span class="app-list-icon">
                      <template v-if="chartApp.content">
                        <img
                          :src="'data:image/png;base64,' + chartApp.content"
                        />
                      </template>
                      <template v-else-if="chartApp.logoUrl">
                        <img
                          v-if="chartApp.logoUrl.indexOf('http') > -1"
                          :src="chartApp.logoUrl"
                        />
                        <img
                          v-else
                          :src="getDownloadUrlNew(chartApp.logoUrl)"
                        />
                      </template>
                      <img v-else :src="defaultIcon" />
                    </span>
                    <span class="tree-item-name">{{
                      getDisplayName(chartApp)
                    }}</span>
                  </div>
                  <div
                    v-for="(appfun, appfunIndex) in chartApp.appFunctionList"
                    :key="appfunIndex"
                    class="app-list-content"
                    :class="{ collapse: chartApp.collapse }"
                  >
                    <div
                      class="tree-item form-list"
                      @click="onAppOrAppFormCollapse(appfun)"
                    >
                      <em
                        class="icon aufontAll caret-icon"
                        :class="
                          appfun.collapse
                            ? 'h-icon-all-caret-right'
                            : 'h-icon-all-caret-down'
                        "
                      ></em>
                      <span class="tree-item-name">
                        <em class="icon aufontAll" :class="appfun.icon"></em>{{ appfun.name }}</span>
                    </div>
                    <div
                      v-for="(apprep, apprepIndex) in appfun.appReportChartList"
                      :key="apprepIndex"
                      class="tree-item report-list"
                      :class="{ collapse: appfun.collapse }"
                    >
                      <span class="tree-item-name">
                        <em class="icon aufontAll h-icon-all-sales-stage-o"></em>{{ apprep.title ? apprep.title : '--' }}</span>
                      <span v-if="apprep.selected" class="add-tips">{{
                        $t('languages.common.workbanch.added')
                      }}</span>
                      <em
                        v-else
                        class="icon aufontAll h-icon-all-plus-circle opt-icon"
                        :class="{
                          disabled: selectedCharts.length >= maxFavoritesCharts,
                        }"
                        @click="addApp(apprep)"
                      ></em>
                    </div>
                  </div>
                </div>
              </template>
            </div>
          </div>
        </div>
        <div class="manage-edit-foot">
          <H3Button class="btn" type="default" @click="popupClose">{{
            $t('languages.common.cancel')
          }}</H3Button>
          <H3Button class="btn" type="primary" @click="onSave">{{
            $t('languages.common.ok')
          }}</H3Button>
        </div>
      </div>
    </h3-popup>
  </div>
</template>

<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import { H3Popup, H3Button } from '@h3/thinking-ui';
import DefaultContent from './default-content.vue';
import Draggable from 'vuedraggable';
import { listApi } from 'cloudpivot/api';
import getDownloadUrlNew from 'cloudpivot/common/src/utils/getDownloadUrlNew';
const icon = require('../assets/app-default-icon.png');
import common from 'cloudpivot/common/pc';

@Component({
  name: 'myCharts',
  components: {
    DefaultContent,
    H3Popup,
    Draggable,
    H3Button,
    PageLoadingUnify: common.components.PageLoadingUnify,
    SingleChartRender: () => import('./single-chart-render.vue'),
  },
})
export default class myCharts extends Vue {
  defaultIcon: string = icon; // 更多应用默认图标

  favoritesCharts: any[] = []; //收藏图表

  manageEdit: boolean = false; //编辑状态

  selectedCharts: any[] = []; //当前已添加的图表

  chartAppList: any[] = []; //所有图表

  loading: boolean = true;

  isLoading: boolean = true;

  dragOptions: any = {
    animation: 150,
    ghostClass: 'ghostClass',
    forceFallback: true,
    fallbackClass: 'dragClass',
    touchStartThreshold: 20,
    delay: 100,
  };

  maxFavoritesCharts: number = 12; //最大可管理图表数量

  load(flag?: boolean) {
    if (flag) {
      this.loading = false;
      this.$h3.toast.hide();
    } else {
      this.loading = true;
      this.$h3.toast.show({
        text: this.$t('languages.common.workbanch.loading'),
        iconType: 'loading',
        autoHide: false,
      });
    }
  }

  /**
   * 名称转换
   */
  getDisplayName(item) {
    let name: string = item.name;
    if (item.name_i18n) {
      const name_i18n =
        typeof item.name_i18n === 'object'
          ? item.name_i18n
          : JSON.parse(item.name_i18n);
      name = name_i18n[this.$i18n.locale] || name;
    }
    return name;
  }

  getDownloadUrlNew(refId: string) {
    return getDownloadUrlNew.getImageUrl(refId);
  }

  created() {
    this.initFavoriteCharts();
  }

  initFavoriteCharts() {
    this.listFavorite().then((res: any) => {
      if (res.errcode === 0) {
        this.favoritesCharts = res.data || [];
      }
      this.isLoading = false;
    });
  }

  async listFavorite() {
    return listApi.listFavoriteChart({ isMobile: true });
  }

  /**
   * 图表配置信息
   */
  get config() {
    return {
      token: localStorage.getItem('token'),
    };
  }

  onManageEdit() {
    this.manageEdit = true;
    this.selectedCharts = [...this.favoritesCharts];
    this.queryReportChartTree();
  }

  /**
   * 取消勾选，不保存任何
   */
  popupClose() {
    this.manageEdit = false;
    this.selectedCharts = [];

    this.chartAppList.forEach((group) => {
      this.$set(group, 'collapse', false);
    });
  }

  /**
   * 保存添加收藏的应用
   */
  onSave() {
    const reportInfoList = this.selectedCharts.map((item) => {
      return {
        reportObjectId: item.objectId,
        chartUuid: item.uuid,
      };
    });
    listApi
      .createFavoriteChart({
        isMobile: true,
        reportInfoList: reportInfoList,
      })
      .then((res: any) => {
        if (res.errcode === 0) {
          this.listFavorite().then((innerRes: any) => {
            if (innerRes.errcode === 0) {
              this.favoritesCharts = innerRes.data || [];
              this.manageEdit = false;
            }
          });
        }
      });
  }

  /**
   * 获取所有报表模型的图表数据
   */
  queryReportChartTree() {
    this.load();
    listApi.queryReportChartTree({ expandAll: false }).then((res: any) => {
      if (res.errcode === 0) {
        this.chartAppList = res.data;
        this.chartAppList.forEach((item) => {
          if (item.appFunctionList && Array.isArray(item.appFunctionList)) {
            item.appFunctionList.forEach((appfun) => {
              appfun.appReportChartList.forEach((apprep) => {
                const selected = this.selectedCharts.some((chart) => {
                  return apprep.uuid === chart.uuid;
                });
                this.$set(apprep, 'selected', selected);

                /**
                 * 根据组件类型赋值默认图表名称
                 */
                switch (apprep.type) {
                  case 'image':
                    apprep.title = apprep.title ? apprep.title : '未命名的图片';
                    break;
                  case 'web':
                    apprep.title = apprep.title ? apprep.title : '未命名的Web';
                    break;
                  default:
                    break;
                }
                apprep.title = apprep.title ? apprep.title : '--';
              });

              // this.$set(appfun, 'collapse', false);
              this.$set(appfun, 'collapse', true);
            });
          }
          // this.$set(item, 'collapse', false);
          this.$set(item, 'collapse', true);
        });
      } else {
        this.chartAppList = [];
      }
      this.load(true);
    });
  }

  /**
   * 应用分组/模型折叠
   */
  onAppOrAppFormCollapse(item) {
    item.collapse = !item.collapse;
    if (!item.collapse) {
      this.queryReportChartTreeChild(item.code);
    }
  }

  async queryReportChartTreeChild(id: string) {
    let arr = this.chartAppList;
    let node = this.filterTree(id, arr);
    const params: any = {
      appCode: id,
      isMobile: true,
    };
    const res = await listApi.queryReportChartTreeByApp(params);
    let appFunctionListArr = res.data.filter((x) => {
      return node.code === x.code;
    });
    if (appFunctionListArr.length) {
      node.appFunctionList = appFunctionListArr[0].appFunctionList;
    }
  }

  filterTree(code: any, arr: any) {
    for (const item of arr) {
      if (item.code === code) {
        return item;
      }
      if (item.children && item.children.length) {
        const _item = this.filterTree(code, item.children);
        if (_item) {
          return _item;
        }
      }
    }
  }

  /**
   * 添加图表
   */
  addApp(report) {
    if (this.selectedCharts.length >= this.maxFavoritesCharts) {
      return;
    }
    this.selectedCharts.push(report);
    report.selected = !report.selected;
  }

  /**
   * 移除已添加的图表
   */
  delApp(report, index) {
    this.selectedCharts.splice(index, 1);
    this.chartAppList.forEach((item) => {
      if (item.appFunctionList && Array.isArray(item.appFunctionList)) {
        item.appFunctionList.forEach((appfun) => {
          appfun.appReportChartList.forEach((apprep) => {
            if (apprep.uuid === report.uuid) {
              this.$set(apprep, 'selected', false);
            }
          });
        });
      }
    });
  }
}
</script>
<style lang="less" scoped>
@import '~@/styles/mixins.less';
.my-charts {
  .px2remSmall(padding-left, 12px);
  .px2remSmall(padding-right, 12px);
  .px2remSmall(padding-top, 16px);
  .px2remSmall(padding-bottom, 16px);
  > .header {
    .px2remSmall(padding-left, 8px);
    .px2remSmall(padding-right, 8px);
  }
  .box-content {
    padding-top: 10px;
    width: 100%;
    .chart-item {
      margin-bottom: 12px;
      width: 100%;
      height: 210px;
      background: #ffffff;
      border-radius: 6px;
      border: 0.5px solid rgba(209, 211, 228, 0.65);
      overflow: hidden;
    }
    .chart-item:last-child {
      margin-bottom: 0;
    }
  }
  /deep/.h3-single-chart {
    border-radius: 6px;
    .h3-dashboard-mobile__item {
      border-radius: 6px;
    }
  }
  .loading-charts {
    min-height: 158px;
  }
}
.tree-item {
  height: 48px;
  line-height: 48px;
  display: flex;
  .caret-icon {
    color: rgba(17, 18, 24, 0.25);
    font-size: 12px;
    scale: 0.75;
    width: 21.5px;
    text-align: center;
  }
  .app-list-icon {
    margin-left: 4px;
    .px2rem(border-radius, 12px);
    img {
      width: 28px;
      height: 28px;
      border-radius: 6px;
    }
  }
  .tree-item-name {
    margin-left: 10px;
    font-size: 15px;
    color: #111218;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    -webkit-user-select: none;
    user-select: none;
    em {
      margin-right: 10px;
    }
  }
}
.form-list {
  padding-left: 30px;
  .tree-item-name {
    margin-left: 4px;
  }
}
.report-list {
  padding-left: 80px;
  justify-content: space-between;
  .tree-item-name {
    margin-left: 0;
  }
  .add-tips {
    font-size: 13px;
    color: rgba(17, 18, 24, 0.5);
  }
  .opt-icon {
    color: #2970ff;
    font-size: 18px;
    -webkit-user-select: none;
    user-select: none;
  }
  .opt-icon.disabled {
    color: #c3c4c5;
  }
  .h-icon-all-minus-circle {
    color: #f0353f;
    margin-left: 12px;
  }
}
.report-list.collapse {
  display: none;
}
.app-list-content.collapse {
  display: none;
}

.body-top,
.body-bottom {
  .sub-content {
    padding-right: 4px;
  }
}

.body-top {
  .report-list {
    padding-left: 0;
    .item-dragable-icon {
      margin-right: 8px;
      font-size: 14px;
      color: #8893a7;
    }
  }
  .report-list.chosen {
    box-shadow: 0px 0px 10px 0px rgba(23, 34, 56, 0.08);
  }
}

.body-bottom {
  .report-list {
    .tree-item-name {
      max-width: 220px;
    }
  }
}
</style>
